package com.mys.maggie.nacos.plugin.refresh;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.registry.NacosRegistration;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.mys.maggie.nacos.plugin.AbstractEndPoint;
import com.mys.maggie.nacos.plugin.pause.GracefulPause;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.stereotype.Component;


@Component
@Endpoint(id = "graceful-refresh")
public class GracefulRefresh extends AbstractEndPoint {
    protected final transient Logger log = LoggerFactory.getLogger(getClass());
    
    @Autowired
    NacosDiscoveryProperties nacosDiscoveryProperties;
    
    @Autowired
    NacosRegistration nacosRegistration;
    
    @Autowired
    AbstractEnvironment environment;
    
    @WriteOperation
    public String up() {
        
        String serviceName = nacosDiscoveryProperties.getService();
        String groupName = nacosDiscoveryProperties.getGroup();
        String clusterName = nacosDiscoveryProperties.getClusterName();
        String ip = nacosDiscoveryProperties.getIp();
        String portStr = StringUtils.isBlank(environment.getProperty("server.port")) ? "8080" : environment.getProperty("server.port");
        int port = (nacosDiscoveryProperties.getPort() == -1) ? Integer.parseInt(portStr) : nacosDiscoveryProperties.getPort();
        String namespace = nacosDiscoveryProperties.getNamespace();
        
        Instance instance = new Instance();
        instance.setIp(ip);
        instance.setPort(port);
        instance.setWeight(1.0);
        instance.setClusterName(clusterName);
        instance.setMetadata(nacosDiscoveryProperties.getMetadata());
        log.info("[上负载]自主==> Namespace:{}, ServiceName:{}, Address:{}:{}, Group:{}, ClusterName:{}", namespace, serviceName, ip, port, groupName, clusterName);
        try {
            nacosRegistration.getNacosNamingService().registerInstance(serviceName, groupName, instance);
        } catch (NacosException e) {
            log.error("[上负载]自主==> " + e.getMessage(), e);
            return "error";
        }
        return "success";
    }
    
    @Component
    public class UpListener implements ApplicationListener<ApplicationEvent> {
        protected final transient Logger log = LoggerFactory.getLogger(getClass());
        @Autowired
        private GracefulRefresh gracefulRefresh;
        @Autowired
        private GracefulPause gracefulPause;

        private final Logger logger = LoggerFactory.getLogger(getClass());
        
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
            if (event instanceof ApplicationReadyEvent) {
                logger.info("[事件] {},开始上负载", event.getClass().getName());
                String result = gracefulRefresh.up();
                log.info("[上负载]自主==> result:{}", result);
            } else if (event instanceof ContextClosedEvent) {
                logger.info("[事件] {},开始下负载", event.getClass().getName());
                String result = gracefulPause.down();
                log.info("自主[下负载]==> result:{}", result);
            } else if (!(event instanceof HeartbeatEvent)) {
                //logger.info("[事件] {}", event.getClass().getName());
            }
        }
    }
}